<?php

class Soul_Classes_Proxy implements ArrayAccess {

	private $_proxyObject = NULL;
	
	public function __construct($proxyObject) {
		$this->_proxyObject = $proxyObject;
	}

	public function __get($name) {
		return $this->_proxyObject->$name;
	}

	public function __set($name, $value) {
		$this->_proxyObject->$name = $value;
	}

	public function __isset($name) {
		return isset($this->_proxyObject[$name]);
	}

	public function __unset($name) {
		unset($this->_proxyObject[$name]);
	}

	public function __call($name, $arguments) {
		Soul_Event_Manager::callReceiver(get_class($this->_proxyObject).'.before'.ucfirst($name),
										 new Soul_Event_Argument($this->_proxyObject, $arguments));
		
		$result = call_user_func_array(array($this->_proxyObject, $name), $arguments);
		$arguments = array_merge($arguments, array('_result'=>$result));
		
		Soul_Event_Manager::callReceiver(get_class($this->_proxyObject).'.after'.ucfirst($name),
										 new Soul_Event_Argument($this->_proxyObject, $arguments));
		
		return $result;
	}

	public function offsetExists($offset) {
		return $this->_proxyObject->offsetExists($offest);
	}

	public function offsetGet($offset) {
		return $this->_proxyObject->offsetGet($offest);
	}

	public function offsetSet($offset, $value) {
		return $this->_proxyObject->offsetSet($offset, $value);
	}

	public function offsetUnset($offset) {
		return $this->_proxyObject->offsetUnset($offest);
	}

	public function isInstanceof($object){
		return $this->_proxyObject instanceof $object;
	}

	private function invokeCallback($callback, $arguments, $result = NULL){
		if(is_array($callback)){
			$className = $callback[0];
			$methodName = $callback[1];
			$obj = Soul_Loader::loadSingleton($className);
			$obj->$methodName($this->_proxyObject, $arguments, $result);
		}else{
			$callback($this->_proxyObject, $arguments, $result);
		}
	}
}